/*
by txdnet.cn tonydon
 */

package txdnet.db;
import java.sql.*;
import java.util.Properties;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;

import txdnet.util.Logger;
/**
 *
 * @author txdnet
 */
public class DbcpPool {
 private static       PoolingDataSource  ds =null;
 private static String             driverName = null;
 private static String             url        = null;
 private static String             user       = null;
 private static String             key   = null;//
 private static int                maxActive  = 8;
 private static long               maxWait    = 3000L;
 private static int                maxIdle    = 8;//
 private static int                minIdle    = 0;//
 private static boolean		   testOnBorrow = true;
 private static boolean            testOnReturn = false;
 private static boolean            testWhileIdle= false;
 private static long               timeBetweenEvictionRunsMillis = -1L;
 private static long               minEvictableIdleTimeMillis = 1800000L;
 private static int                numTestsPerEvictionRun = 3;
 private static       DbcpPool       dbcpPool  =init();


/**
  * Default Constructor. Takes no arguments
  */
    private DbcpPool()  throws SQLException {}


private DbcpPool(String url, String user, String password)  throws Exception
{
		//使用数据连接池提高数据库读取效率

		Class.forName(driverName);
		GenericObjectPool connPool = new GenericObjectPool(null);
		connPool.setMaxActive(maxActive);  //最大激活数－在Pool中注册并且正在使用的实例数
		connPool.setMaxWait(maxWait);
		connPool.setMaxIdle(maxIdle);   //最大空闲数－在Pool中注册
		connPool.setMinIdle(minIdle);
		//When true, objects will be validated before being returned by the borrowObject() method. If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another.
		connPool.setTestOnBorrow(testOnBorrow );//true
		//When true, objects will be validated before being returned to the pool within the returnObject(java.lang.Object).
		connPool.setTestOnReturn(testOnReturn );//false
		//When true, objects will be validated by the idle object evictor (if any). If an object fails to validate, it will be dropped from the pool.
		connPool.setTestWhileIdle(testWhileIdle );//false
		//Sets the number of milliseconds to sleep between runs of the idle object evictor thread. When non-positive, no idle object evictor thread will be run.
		connPool.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis );
		//设定在进行后台对象清理时休眠时间超过了1800s的对象为过期
		connPool.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis );
		//3表示清理时检查3个线程
                connPool.setNumTestsPerEvictionRun(numTestsPerEvictionRun );

        //
        // Next, we'll create a ConnectionFactory that the
        // pool will use to create Connections.
        // We'll use the DriverManagerConnectionFactory,
        // using the connect string passed in the command line
        // arguments.
        //
        ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(url,user,password);
        //
        // Now we'll create the PoolableConnectionFactory, which wraps
        // the "real" Connections created by the ConnectionFactory with
        // the classes that implement the pooling functionality.
        //
        PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connPool,null,null,false,true);

        //
        // Finally, we create the PoolingDriver itself,
        // passing in the object pool we created.
        //
		ds = new PoolingDataSource(connPool);

}

public static Connection getConnection() throws Exception
{
	        return ds.getConnection();
}


private static DbcpPool init(){
    Properties p = null;
try{
     p = PoolFactory.getDbProperties();
     driverName = p.getProperty("dbcp.DriverName");
     user       = p.getProperty("dbcp.DataBaseUser");
     key   = p.getProperty("dbcp.DataBaseKey");
     url        = p.getProperty("dbcp.ConnectUrl");
     maxActive  = Integer.parseInt( p.getProperty("dbcp.MaxActive"));
     maxWait    = Long.parseLong( p.getProperty("dbcp.MaxWait"));
     maxIdle    = Integer.parseInt( p.getProperty("dbcp.MaxIdle"));
     minIdle    = Integer.parseInt( p.getProperty("dbcp.MinIdle"));
     timeBetweenEvictionRunsMillis    = Long.parseLong( p.getProperty("dbcp.TimeBetweenEvictionRunsMillis"));
     minEvictableIdleTimeMillis    = Long.parseLong( p.getProperty("dbcp.MinEvictableIdleTimeMillis"));
     numTestsPerEvictionRun    = Integer.parseInt( p.getProperty("dbcp.NumTestsPerEvictionRun"));
     testOnBorrow = Boolean.parseBoolean(p.getProperty("dbcp.TestOnBorrow"));
     testOnReturn = Boolean.parseBoolean(p.getProperty("dbcp.TestOnReturn"));
     testWhileIdle = Boolean.parseBoolean(p.getProperty("dbcp.TestWhileIdle"));
     dbcpPool = new DbcpPool(url, user, key);
   }catch(Exception e){
           Logger.error(DbcpPool.class, e.toString());
           dbcpPool=null;
   }
return dbcpPool;
}
}